package com.fast.alden.admin.service.impl;

import com.fast.alden.admin.entity.dto.UserProfile;
import com.fast.alden.admin.service.*;
import com.fast.alden.admin.util.SecurityUtils;
import com.fast.alden.common.entity.dto.ChangePasswordParam;
import com.fast.alden.common.exception.BizException;
import com.fast.alden.common.exception.BizExceptionEnum;
import com.fast.alden.data.model.*;
import com.fast.alden.data.repo.SysUserRepository;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;

@Service
public class PersonalCenterServiceImpl implements PersonalCenterService {
    @Resource
    private SysUserRepository userRepository;
    @Resource
    private SysRoleService roleService;
    @Resource
    private SysPositionService positionService;
    @Resource
    private SysDepartmentService departmentService;
    @Resource
    private SysMenuService menuService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private AuthService authService;

    @Override
    public UserProfile retrieve() {
        SysUser current = SecurityUtils.getCurrentUser();
        SysUser user = userRepository.findById(current.getId()).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, current.getId()));
        SysDepartment department = user.getDepartmentId() != null ? departmentService.retrieveWithException(user.getDepartmentId()) : null;
        List<SysRole> roles = roleService.findAllByUserId(user.getId());
        List<SysPosition> positions = positionService.findAllByUserId(user.getId());
        // 如果是管理员，直接获取所有菜单权限；否则根据拥有的角色查询可操作的菜单
        List<SysMenu> menus = user.getType() == 0 ? menuService.tree() : menuService.treeListByRoleIds(roles.stream().map(SysRole::getId).toList());

        UserProfile profile = new UserProfile();
        profile.setUser(user);
        profile.setDepartment(department);
        profile.setRoles(roles);
        profile.setPositions(positions);
        profile.setMenus(menus);

        return profile;
    }

    @Override
    @Transactional
    public void update(SysUser user) {
        SysUser current = SecurityUtils.getCurrentUser();
        if (!current.getId().equals(user.getId())) {
            throw new BizException(BizExceptionEnum.USER_ID_IS_NOT_CURRENT);
        }
        current = userRepository.findById(current.getId()).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, user.getId()));
        // 编辑个人信息，仅可修改昵称、真实姓名、邮箱、电话、生日、个人简介
        current.setNickname(user.getNickname());
        current.setRealName(user.getRealName());
        current.setEmail(user.getEmail());
        current.setPhone(user.getPhone());
        current.setBirthday(user.getBirthday());
        current.setIntroduce(user.getIntroduce());

        userRepository.save(current);
    }

    @Override
    public void changePassword(ChangePasswordParam param) {
        SysUser current = SecurityUtils.getCurrentUser();
        SysUser user = userRepository.findById(current.getId()).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, current.getId()));

        authService.checkVerifyCode(param.getVerifyCodeKey(), param.getVerifyCode());

        if (!passwordEncoder.matches(param.getOldPassword(), user.getPassword())) {
            throw new BizException(BizExceptionEnum.USER_OLD_PASSWORD_IS_WRONG);
        }
        if (param.getOldPassword().equals(param.getNewPassword())) {
            throw new BizException(BizExceptionEnum.NEW_PASSWORD_IS_SAME_AS_OLD_PASSWORD);
        }
        user.setPassword(passwordEncoder.encode(param.getNewPassword()));
        userRepository.save(user);
        authService.logout();
    }

    @Override
    public void updateAvatar(MultipartFile file) throws IOException {
        SysUser current = SecurityUtils.getCurrentUser();
        SysUser user = userRepository.findById(current.getId()).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, current.getId()));

        InputStream inputStream = file.getInputStream();
        byte[] bytes = new byte[inputStream.available()];
        int size = inputStream.read(bytes);

        user.setAvatar("data:image/png;base64," + Base64.getEncoder().encodeToString(bytes));
        userRepository.save(user);
    }

    @Override
    public void removeAvatar() {
        SysUser current = SecurityUtils.getCurrentUser();
        SysUser user = userRepository.findById(current.getId()).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, current.getId()));

        user.setAvatar(null);
        userRepository.save(user);
    }
}
